using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;             // required for Message
using System.Runtime.InteropServices;   // required for Marshal
using System.IO;
using Microsoft.Win32.SafeHandles;     
// DeviceChangedListener - rev. 1, Oct. 31 2007

namespace Universe.WinForms.Broadcast
{
    /// <summary>
    /// Hidden Form which we use to receive Windows messages about flash drives
    /// </summary>
    internal class DeviceListenerForm : Form
    {
        private Label label1;
        private DeviceChangedListener _MChangedListener = null;

        /// <summary>
        /// Set up the hidden form. 
        /// </summary>
        /// <param name="changedListener">DriveDetector object which will receive notification about USB drives, see WndProc</param>
        public DeviceListenerForm(DeviceChangedListener changedListener)
        {
            _MChangedListener = changedListener;
            this.MinimizeBox = false;
            this.MaximizeBox = false;
            this.ShowInTaskbar = false;
            this.ShowIcon = false;
            this.FormBorderStyle = FormBorderStyle.None;
            this.Load += new System.EventHandler(this.Load_Form);
            this.Activated += new EventHandler(this.Form_Activated);
        }

        private void Load_Form(object sender, EventArgs e)
        {
            // We don't really need this, just to display the label in designer ...
            InitializeComponent();

            // Create really small form, invisible anyway.
            this.Size = new System.Drawing.Size(5, 5);
        }

        private void Form_Activated(object sender, EventArgs e)
        {
            this.Visible = false;
        }

        /// <summary>
        /// This function receives all the windows messages for this window (form).
        /// We call the DeviceChangedListener from here so that is can pick up the messages about
        /// drives arrived and removed.
        /// </summary>
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);

            if (_MChangedListener != null)
            {
                _MChangedListener.WndProc(ref m);
            }
        }

        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(13, 30);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(362, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "This is invisible form. To see DeviceChangedListener code click View Code";
            // 
            // DeviceListenerForm
            // 
            this.ClientSize = new System.Drawing.Size(400, 82);
            this.Controls.Add(this.label1);
            this.Name = "DeviceListenerForm";
            this.ResumeLayout(false);
            this.PerformLayout();

        }
    }

    public delegate void DeviceChangedEventHandler(Object sender, DriveDetectorEventArgs e);

    /// <summary>
    /// Our class for passing in custom arguments to our event handlers 
    /// 
    /// </summary>
    public class DriveDetectorEventArgs : EventArgs 
    {


        public DriveDetectorEventArgs()
        {
            Cancel = false;
            Drive = "";
            HookQueryRemove = false;
        }


        public DriveDetectorEventArgs(string drive)
        {
            Drive = drive;
        }

        /// <summary>
        /// Get/Set the value indicating that the event should be cancelled 
        /// Only in QueryRemove handler.
        /// </summary>
        public bool Cancel;

        /// <summary>
        /// Drive letter for the device which caused this event 
        /// </summary>
        public readonly string Drive;

        /// <summary>
        /// Set to true in your DeviceArrived event handler if you wish to receive the 
        /// QueryRemove event for this drive. 
        /// </summary>
        public bool HookQueryRemove;

    }
}